package cn.datawin.task;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.datawin.cotask.client.ClientPool;
import cn.datawin.spider.httputil.HttpRequest;
import cn.datawin.spider.httputil.HttpRequest.Method;
import cn.datawin.spider.httputil.HttpService;
import cn.datawin.spider.page.Page;
import cn.datawin.spider.pipeline.PipeLine;
import cn.datawin.spider.processor.Processor;
import cn.datawin.spider.scheduler.PageQueue;
import cn.datawin.task.page.Taskpage;
import cn.datawin.task.util.HttpUtil;
import cn.datawin.task.util.PaserUtil;
import cn.datawin.task.util.SpiderUtil;
import cn.datawin.task.util.TaskUtil;

public class PrepareTask implements Runnable{
	public static PageQueue pageQueue = new PageQueue();
	
	private String workbeach;
	private String state;
	private boolean stop = false;
	public PrepareTask() {
	}
	
	public PrepareTask(String workbeach, String state) {
		super();
		this.workbeach = workbeach;
		this.state = state;
	}


	void offerTask() throws Exception {
		List<Task> tasks = PaserUtil.dboToTask(TaskUtil.gettask(workbeach, state, Config.apps.get("getTaskNum")));
		while(tasks.size()>0){
			Task task = tasks.remove(0);
			if(task.isBranch()){
				branchTask(task);
				continue;
			}else{
				Page page = task2page(task);
				pageQueue.offer(page);
			}
		}
		Collections.shuffle(pageQueue.getQueue()); //乱序
	}

	
	Page task2page(Task task) {
		task.next();  // 修复 branch 出现的 主rule未执行的问题
		task.setProcessor(task.currentRule().getType());
		Page page = new Taskpage();
		Processor processor = SpiderUtil.getProcessor(task.getProcessor());
		PipeLine pipeLine = SpiderUtil.getPipeLine(task.getProcessor());
		processor.setTask(task);
		page.setProcessor(processor);
		page.setPipeLine(pipeLine);
		HttpService httpservice = HttpUtil.getHttpClient();
		if(task.getHttpClientid()!= null&&!task.getHttpClientid().isEmpty()){
			httpservice = ClientPool.get(task.getHttpClientid());
		}
		page.setHttpService(httpservice);
		HttpRequest req = new HttpRequest(task.getUrl());
		
		Rule rule = new Rule(task.currentRule());
		req.setCharset(rule.getCharset());
		req.setCookies(task.getCookie());
		req.setConnectTimeout(6000);
		req.setReadTimeout(6000);
		req.setMethod(rule.getMethod().equalsIgnoreCase("post") ? Method.post : Method.get);
		req.setHeaders(task.getHeader());
		req.setPostParams(rule.getData());
		page.setHttpRequest(req);
		return page;

	}
	

	void branchTask(Task task) throws Exception{
		List<Map<String, Object>> rules =  task.getRules();
		List<List<Map<String, Object>>> _rules = new ArrayList<List<Map<String,Object>>>();
		List<Task> tasks = new ArrayList<Task>();
		for(final Map<String, Object> map: rules){
			List<Map<String, Object>> rule = new ArrayList<Map<String,Object>>(){
				{add(map);}
			};
			_rules.add(rule);
			
			task.setProcessor((String)rule.get(0).get("type"));
			task.setClient(task.getClient());
			tasks.add((Task) task.clone());
		}
		
		Map<String, String> obj = new HashMap<String, String>();
		obj.put("serializeList", HttpUtil.serialize(tasks));
		obj.put("rules", HttpUtil.serialize(_rules));
		TaskUtil.addtask(obj);
		Statistic.getInstance().addCount(task);
		if("true".equals(Config.apps.get("isReport"))){
			TaskUtil.comptask(task.getId());
		}
	}
	
	
	int times = 0;
	@Override
	public void run() {
		while(!stop){
			try{
				if(pageQueue.size()==0){
					offerTask();
				}
				if(times==0){
					TaskUtil.updateclient(Config.apps.get("workbeach"),0+"");
				}else if(times%6==0){
					TaskUtil.updateclient(Config.apps.get("workbeach"),Statistic.getInstance().getCount()+"");
				}
				times++;
				Thread.sleep(10000);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	public boolean isStop() {
		return stop;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}
	
	public void start(){
		new Thread(this).start();
	}
}
